home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-04
/
adg_7_8.zip
/
SETUP.C
< prev
next >
Wrap
Text File
|
1991-02-21
|
14KB
|
409 lines
/****************************************************************************
Module name: Setup.C
Programmer : Jeffrey M. Richter.
*****************************************************************************/
#include "..\nowindws.h"
#undef NOATOM
#undef NOCTLMGR
#undef NOKERNEL
#undef NOLFILEIO
#undef NOLSTRING
#undef NOMB
#undef NOMEMMGR
#undef NOMINMAX
#undef NOMSG
#undef NOOPENFILE
#undef NORESOURCE
#undef NOSHOWWINDOW
#undef NOSYSMETRICS
#undef NOUSER
#undef NOWINMESSAGES
#undef NOWINOFFSETS
#undef NOWINSTYLES
#include <windows.h>
#include <dde.h>
#include <dos.h>
#include <direct.h>
#include <string.h>
#include "Setup.H"
#include "SetupInf.H"
#include "..\Meter.04\Meter.H"
BOOL NEAR PASCAL CreateDstDirTree (HWND hDlgStatus);
BOOL NEAR PASCAL CopyAllFiles (HWND hDlgStatus);
BOOL NEAR PASCAL CreatePMInfo (HANDLE hInstance);
#define WasCancelled(hDlg) (!IsWindowEnabled(GetDlgItem(hDlg, IDCANCEL)))
char _szAppName[] = "Setup";
HANDLE _hInstance;
char _szSrcDir[MAXDIR] = "x:\\"; // Where SETUP.EXE was run from.
char _szDstDir[MAXDIR];
int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow) {
int nResult;
HWND hDlgStatus;
FARPROC fpStatDlgProc, fpProc;
HANDLE hLibMeter;
DWORD dwDiskSpaceNeeded, dwFreeDiskSpace;
struct diskfree_t DiskFreeSpace;
char szBuf[100];
// Don't let another instance of this application execute.
if (hPrevInstance != NULL) return(0);
// Prepare the DDE Client window class so that we can use it later.
if (!RegisterDDEClient(hInstance)) return(0);
// Initialize the default source path so that it uses the same drive
// letter that the SETUP.EXE application was executed from.
GetModuleFileName(hInstance, _szSrcDir, sizeof(_szSrcDir));
*(_fstrrchr(_szSrcDir, '\\') + 1) = 0;
_hInstance = hInstance;
// Check that the METER.DLL is available at the beginning.
wsprintf(szBuf, "%sMETER.DLL", (LPSTR) _szSrcDir);
hLibMeter = LoadLibrary(szBuf);
if (hLibMeter < 32) {
MsgBox(hInstance, NULL, IDS_NOMETERLIB, _szAppName,
MB_ICONINFORMATION | MB_OK | MB_TASKMODAL);
return(0);
}
// Read the SETUP.INF file into memory.
wsprintf(szBuf, "%s%sSETUP.INF", (LPSTR) _szSrcDir, (LPSTR)
((*(_fstrrchr(_szSrcDir, '\\') + 1) == 0) ? "" : "\\"));
nResult = (SIM_INITIALIZE_ERROR) SetupInfoSys(SIM_INITIALIZE, 0, szBuf);
if (nResult != SIM_INIT_NOERROR) {
MsgBox(hInstance, NULL,
(nResult == SIM_INIT_NOMEM) ? IDS_NOMEMORY : IDS_NOSETUPINFOFILE,
_szAppName, MB_ICONINFORMATION | MB_OK | MB_TASKMODAL,
(LPSTR) szBuf);
FreeLibrary(hLibMeter);
return(0);
}
// Get the amount of memory (in K) that is needed for the installation.
dwDiskSpaceNeeded = SetupInfoSys(SIM_GETSPACENEEDED, 0, 0);
// Create the Status dialog box.
fpStatDlgProc = MakeProcInstance(StatusDlgProc, hInstance);
hDlgStatus = CreateDialog(hInstance, MAKEINTRESOURCE(DLG_STATUS),
NULL, fpStatDlgProc);
do {
// Welcome user to setup program and prompt for destination directory.
fpProc = MakeProcInstance(WelcomeDlgProc, hInstance);
nResult = DialogBox(hInstance, MAKEINTRESOURCE(DLG_WELCOME),
NULL, fpProc);
FreeProcInstance(fpProc);
if (nResult == IDCANCEL) break;
// check if there is sufficient disk space on the destination drive.
_dos_getdiskfree(_szDstDir[0] - 'A' + 1, &DiskFreeSpace);
dwFreeDiskSpace = ((DWORD) DiskFreeSpace.avail_clusters *
(DWORD) DiskFreeSpace.sectors_per_cluster *
(DWORD) DiskFreeSpace.bytes_per_sector) / 1024UL;
if (dwFreeDiskSpace < dwDiskSpaceNeeded) {
MsgBox(hInstance, NULL, IDS_NODISKSPACE, _szAppName,
MB_OK | MB_ICONINFORMATION | MB_TASKMODAL,
_szDstDir[0], dwFreeDiskSpace, dwDiskSpaceNeeded);
continue;
}
// Try to create the destination directory tree.
ShowWindow(hDlgStatus, SW_SHOW);
UpdateWindow(hDlgStatus);
nResult = CreateDstDirTree(hDlgStatus);
ShowWindow(hDlgStatus, SW_HIDE);
if (nResult == FALSE) {
// If the directory tree cannot be created, force loop to repeat.
dwFreeDiskSpace = 0;
}
} while (dwFreeDiskSpace < dwDiskSpaceNeeded);
if (nResult == IDCANCEL) {
DestroyWindow(hDlgStatus);
FreeProcInstance(fpStatDlgProc);
FreeLibrary(hLibMeter);
return(0);
}
// Make the destination directory the current directory.
chdir(_szDstDir);
// Try to copy the files.
ShowWindow(hDlgStatus, SW_SHOW);
UpdateWindow(hDlgStatus);
nResult = CopyAllFiles(hDlgStatus);
ShowWindow(hDlgStatus, SW_HIDE);
// Cleanup the things that we no longer need.
DestroyWindow(hDlgStatus);
FreeProcInstance(fpStatDlgProc);
FreeLibrary(hLibMeter);
if (nResult == FALSE) {
// Installation not complete.
MsgBox(hInstance, NULL, IDS_SETUPNOGOOD, _szAppName,
MB_OK | MB_ICONINFORMATION | MB_TASKMODAL);
return(0);
}
MsgBox(hInstance, NULL,
CreatePMInfo(hInstance) ? IDS_PMADDOK : IDS_PMADDNOGOOD,
_szAppName, MB_OK | MB_ICONINFORMATION | MB_TASKMODAL);
return(0);
}
// ********** Functions for Creating the destination directory tree **********
BOOL NEAR PASCAL CreateDstDirTree (HWND hDlgStatus) {
int nResult, nMaxDirs, nDirNum;
char szBuf[MAXDIR]; MSG Msg;
SetDlgItemText(hDlgStatus, ID_STATLINE1, "Creating destination directory tree...");
nMaxDirs = (int) SetupInfoSys(SIM_GETNUMDIRS, 0, 0);
SendDlgItemMessage(hDlgStatus, ID_METER, MM_SETPARTSCOMPLETE, 0, 0);
SendDlgItemMessage(hDlgStatus, ID_METER, MM_SETPARTSINJOB, nMaxDirs + 1, 0);
SetDlgItemText(hDlgStatus, ID_STATLINE2, _szDstDir);
// Create the destination directory.
nResult = chdir(_szDstDir);
if (nResult != 0) {
nResult = mkdir(_szDstDir);
if (nResult != 0) {
MsgBox(_hInstance, hDlgStatus, IDS_CANTMAKEDIR, _szAppName,
MB_ICONINFORMATION | MB_OK, (LPSTR) _szDstDir);
return(FALSE);
} else chdir(_szDstDir);
}
SendDlgItemMessage(hDlgStatus, ID_METER, MM_SETPARTSCOMPLETE, 1, 0);
// Create any subdirectories under the destination directory.
for (nDirNum = 0; nDirNum < nMaxDirs; nDirNum++) {
// Let some other applications execute.
while (PeekMessage(&Msg, NULL, NULL, NULL, PM_REMOVE)) {
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
if (WasCancelled(hDlgStatus)) {
nResult = IDCANCEL;
break;
}
wsprintf(szBuf, "%s%s", (LPSTR) _szDstDir,
(LPSTR) ((*(_fstrrchr(_szDstDir, '\\') + 1) == 0) ? "" : "\\"));
SetupInfoSys(SIM_GETDIR, nDirNum, _fstrchr(szBuf, 0));
SetDlgItemText(hDlgStatus, ID_STATLINE2, szBuf);
nResult = chdir(szBuf);
if (nResult != 0) {
nResult = mkdir(szBuf);
if (nResult != 0) {
MsgBox(_hInstance, hDlgStatus, IDS_CANTMAKEDIR, _szAppName,
MB_ICONINFORMATION | MB_OK, (LPSTR) szBuf);
nResult = IDCANCEL;
break;
} else chdir(szBuf);
}
nResult = IDOK;
SendDlgItemMessage(hDlgStatus, ID_METER, MM_SETPARTSCOMPLETE, nDirNum + 2, 0);
}
return(nResult != IDCANCEL);
}
// ******************* Functions for Copying Files ***************************
typedef enum {
CFE_NOERROR,
CFE_NOMEMORY,
CFE_CANTOPENSRC,
CFE_CANTOPENDST,
} COPYFILE_ERROR;
COPYFILE_ERROR NEAR PASCAL CopyFile (LPSTR szSrcPath, LPSTR szDstPath) {
const WORD wBufferSize = 65535u;
int nSrcFile, nDstFile;
WORD wBytesRead, wDate, wTime;
OFSTRUCT ofSrc, ofDst;
LPSTR lpBuffer;
GLOBALHANDLE hMem;
nSrcFile = OpenFile(szSrcPath, &ofSrc, OF_READ);
if (nSrcFile == -1) return(CFE_CANTOPENSRC);
hMem = GlobalAlloc(GMEM_MOVEABLE, wBufferSize);
if (hMem == NULL) {
_lclose(nSrcFile);
return(CFE_NOMEMORY);
}
nDstFile = OpenFile(szDstPath, &ofDst, OF_CREATE | OF_WRITE);
if (nDstFile == -1) {
_lclose(nSrcFile);
GlobalFree(hMem);
return(CFE_CANTOPENDST);
}
lpBuffer = GlobalLock(hMem);
do {
wBytesRead = _lread(nSrcFile, lpBuffer, wBufferSize);
_lwrite(nDstFile, lpBuffer, wBytesRead);
} while (wBytesRead == wBufferSize);
GlobalUnlock(hMem);
// Make the destination file have the same time stamp as the source file.
_dos_getftime(nSrcFile, &wDate, &wTime);
_dos_setftime(nDstFile, wDate, wTime);
_lclose(nDstFile);
GlobalFree(hMem);
_lclose(nSrcFile);
return(CFE_NOERROR);
}
BOOL NEAR PASCAL CopyAllFiles (HWND hDlgStatus) {
int nMaxFiles, nFileNum, nResult; COPYFILE_ERROR CFE;
char szSrcPath[MAXPATH], szDstPath[MAXPATH], szFileName[MAXFILENAME];
char szFileDesc[MAXFILEDESC], szDir[MAXDIRDESC], szDiskDesc[MAXDISKDESC];
MSG Msg; FARPROC fpProc;
HANDLE hDlgRes;
// Get the handle of the "InsertDisk" dialog box from the EXEcutable file.
hDlgRes = FindResource(_hInstance, MAKEINTRESOURCE(DLG_INSERTDISK), RT_DIALOG);
// Get the memory handle of the "InsertDisk" dialog box in memory.
// The block is already in memory because the dialog box is marked as
// PRELOAD FIXED.
hDlgRes = LoadResource(_hInstance, hDlgRes);
// Force the memory block to be locked down. This prohibits Windows
// from discarding the dialog box template from memory.
LockResource(hDlgRes);
SetDlgItemText(hDlgStatus, ID_STATLINE1, "Copying files...");
nMaxFiles = (int) SetupInfoSys(SIM_GETNUMFILES, 0, 0);
SendDlgItemMessage(hDlgStatus, ID_METER, MM_SETPARTSCOMPLETE, 0, 0);
SendDlgItemMessage(hDlgStatus, ID_METER, MM_SETPARTSINJOB, nMaxFiles, 0);
fpProc = MakeProcInstance(InsertDiskDlgProc, _hInstance);
for (nFileNum = 0; nFileNum < nMaxFiles; nFileNum++) {
SetupInfoSys(SIM_GETFILEDESC, nFileNum, szFileDesc);
SetupInfoSys(SIM_GETFILENAME, nFileNum, szFileName);
SetupInfoSys(SIM_GETFILEDIR, nFileNum, szDir);
SetupInfoSys(SIM_GETFILEDISK, nFileNum, szDiskDesc);
SetDlgItemText(hDlgStatus, ID_STATLINE2, szFileDesc);
wsprintf(szDstPath, "%s%s%s\\%s", (LPSTR) _szDstDir, (LPSTR)
((*(_fstrrchr(_szDstDir, '\\') + 1) == 0) ? "" : "\\"),
(LPSTR) szDir, (LPSTR) szFileName);
do {
// Let other applications execute.
while (PeekMessage(&Msg, NULL, NULL, NULL, PM_REMOVE)) {
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
if (WasCancelled(hDlgStatus)) {
nResult = IDCANCEL;
break;
}
wsprintf(szSrcPath, "%s%s%s\\%s", (LPSTR) _szSrcDir, (LPSTR)
((*(_fstrrchr(_szSrcDir, '\\') + 1) == 0) ? "" : "\\"),
(LPSTR) szDir, (LPSTR) szFileName);
nResult = IDOK;
if (!SetupInfoSys(SIM_ISFILECOMPRESSED, nFileNum, 0)) {
CFE = CopyFile(szSrcPath, szDstPath);
switch (CFE) {
case CFE_NOERROR:
nResult = IDOK;
break;
case CFE_NOMEMORY:
nResult = MsgBox(_hInstance, hDlgStatus, IDS_NOMEMORYCOPY,
_szAppName, MB_ICONINFORMATION | MB_RETRYCANCEL);
break;
case CFE_CANTOPENSRC:
nResult = DialogBoxParam(_hInstance,
MAKEINTRESOURCE(DLG_INSERTDISK), hDlgStatus, fpProc,
(LONG) (LPSTR) szDiskDesc);
// Normally, Windows would have discarded the dialog box
// template from memory after the dialog box had been
// created. By forcing the memory block to be locked by the
// call to LockResource() above, the template will NOT be
// discarded. If the template were discarded, the next time
// this dialog box needed to be created Windows would have
// to load the template from the EXEcutable file. However,
// the SETUP.EXE file is probably not on the diskette that
// is currently in the drive. This would cause the program
// to behave erratically.
break;
case CFE_CANTOPENDST:
nResult = MsgBox(_hInstance, hDlgStatus, IDS_CANTOPENDST,
_szAppName, MB_ICONINFORMATION | MB_RETRYCANCEL);
break;
}
} else {
// Use decompression function to copy the file.
}
// Make sure that the user really wants to cancel Setup.
if (nResult == IDCANCEL) {
nResult = MsgBox(_hInstance, hDlgStatus, IDS_QUERYABORT,
_szAppName, MB_ICONQUESTION | MB_YESNO);
if (nResult == IDYES) {
nResult = IDCANCEL;
break;
}
}
} while (nResult != IDCANCEL && CFE != CFE_NOERROR);
if (nResult == IDCANCEL) break;
SendDlgItemMessage(hDlgStatus, ID_METER, MM_SETPARTSCOMPLETE,
nFileNum + 1, 0);
}
// The dialog box template is no longer necessary to keep around so
// it may be unlocked and removed from memory.
UnlockResource(hDlgRes);
FreeResource(hDlgRes);
FreeProcInstance(fpProc);
return(nResult != IDCANCEL);
}
// *********************** Miscellaneous Function ****************************
int FAR cdecl MsgBox (HANDLE hInstance, HWND hWnd, WORD wID,
LPSTR szCaption, WORD wType, ...) {
char szResString[200], szText[200];
void FAR *VarArgList = (WORD FAR *) &wType + 1;
LoadString(hInstance, wID, szResString, sizeof(szResString) - 1);
wvsprintf(szText, szResString, VarArgList);
return(MessageBox(hWnd, szText, szCaption, wType));
}